/**
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 * <p>
 * http://www.apache.org/licenses/LICENSE-2.0
 * <p>
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package io.gitee.huangjianbo.supos.openapi.core.tools;

import com.alibaba.fastjson2.JSON;

import io.gitee.huangjianbo.supos.openapi.core.http.HttpContentType;
import io.gitee.huangjianbo.supos.openapi.core.http.request.MultipartFormDataPair;

import java.util.*;
import java.util.stream.Collectors;

/**
 * @author tomcat
 * @version 1.0
 */
public final class ObjectUtils {

    /**
     * 判断是否为NULL
     *
     * @param obj 源
     * @return 是或否
     */
    public static boolean isNull(Object obj) {
        return Objects.isNull(obj);
    }

    /**
     * 判断是否不为NULL
     *
     * @param obj 源
     * @return 是或否
     */
    public static boolean isNotNull(Object obj) {
        return !isNull(obj);
    }

    /**
     * 将Ojbect转为字符串
     *
     * @param obj            源
     * @param useEnumOrdinal 是否使用枚举序号
     * @param useMapKey      是否使用枚举名称
     * @return 转换后的字符串
     */
    public static String objectToString(Object obj, final boolean useEnumOrdinal, final boolean useMapKey) {
        if (isNull(obj)) {
            return "";
        } else if (String.class.isAssignableFrom(obj.getClass())) {
            return (String) obj;
        } else if (Integer.class.isAssignableFrom(obj.getClass())) {
            return ((Integer) obj).toString();
        } else if (Boolean.class.isAssignableFrom(obj.getClass())) {
            return ((Boolean) obj).toString();
        } else if (Long.class.isAssignableFrom(obj.getClass())) {
            return ((Long) obj).toString();
        } else if (Double.class.isAssignableFrom(obj.getClass())) {
            return ((Double) obj).toString();
        } else if (Enum.class.isAssignableFrom(obj.getClass())) {
            return useEnumOrdinal ? Integer.toString(((Enum<?>) obj).ordinal()) : ((Enum<?>) obj).name();
        } else if (Map.class.isAssignableFrom(obj.getClass())) {
            Map<?, ?> map = (Map<?, ?>) obj;
            List<String> values = map.entrySet().stream().map(entry ->
                    useMapKey ? objectToString(entry.getKey(), useEnumOrdinal, true)
                            : objectToString(entry.getValue(), useEnumOrdinal, false)).collect(Collectors.toList());
            return StringUtils.join(values, ",");
        } else if (Collection.class.isAssignableFrom(obj.getClass())) {
            Collection<?> collection = (Collection<?>) obj;
            List<String> values = collection.stream().map(item ->
                    objectToString(item, useEnumOrdinal, useMapKey)).collect(Collectors.toList());
            return StringUtils.join(values, ",");
        } else if (obj.getClass().isArray()) {
            List<String> values = Arrays.stream((Object[]) obj).map(item ->
                    objectToString(item, useEnumOrdinal, useMapKey)).collect(Collectors.toList());
            return StringUtils.join(values, ",");
        } else {
            return obj.toString();
        }
    }

    /**
     * 将对象转换为multipart/form-data的数据
     *
     * @param name           form-data的名称
     * @param obj            对象
     * @param useEnumOrdinal 是否使用枚举序号
     * @return multipart/form-data的数据列表
     */
    public static MultipartFormDataPair objectToFormDataString(String name, Object obj, final boolean useEnumOrdinal) {
        if (isNull(obj)) {
            return null;
        } else if (String.class.isAssignableFrom(obj.getClass())) {
            return MultipartFormDataPair.of(name, HttpContentType.TEXT_PLAIN, (String) obj);
        } else if (Integer.class.isAssignableFrom(obj.getClass())) {
            return MultipartFormDataPair.of(name, HttpContentType.TEXT_PLAIN, ((Integer) obj).toString());
        } else if (Boolean.class.isAssignableFrom(obj.getClass())) {
            return MultipartFormDataPair.of(name, HttpContentType.TEXT_PLAIN, ((Boolean) obj).toString());
        } else if (Long.class.isAssignableFrom(obj.getClass())) {
            return MultipartFormDataPair.of(name, HttpContentType.TEXT_PLAIN, ((Long) obj).toString());
        } else if (Double.class.isAssignableFrom(obj.getClass())) {
            return MultipartFormDataPair.of(name, HttpContentType.TEXT_PLAIN, obj.toString());
        } else if (Enum.class.isAssignableFrom(obj.getClass())) {
            return MultipartFormDataPair.of(name, HttpContentType.TEXT_PLAIN,
                    useEnumOrdinal ? Integer.toString(((Enum<?>) obj).ordinal()) : ((Enum<?>) obj).name());
        } else if (Map.class.isAssignableFrom(obj.getClass())) {
            return MultipartFormDataPair.of(name, HttpContentType.APPLICATION_JSON, JSON.toJSONString(obj));
        } else if (Collection.class.isAssignableFrom(obj.getClass())) {
            return MultipartFormDataPair.of(name, HttpContentType.APPLICATION_JSON, JSON.toJSONString(obj));
        } else if (obj.getClass().isArray()) {
            return MultipartFormDataPair.of(name, HttpContentType.APPLICATION_JSON, JSON.toJSONString(obj));
        } else {
            return MultipartFormDataPair.of(name, HttpContentType.APPLICATION_JSON, JSON.toJSONString(obj));
        }
    }
}
